
from django.db import models
from django.core.cache import cache
from django.contrib.auth.models import User

import mistune
from mdeditor.fields import MDTextField


# class ArticleManager(models.Manager):
#     '''模型管理器'''
#     # 改变原有的查询结果集
#     # 封装方法：操作模型类对应的数据表（增删改查）
#     # 使用: Article.object.get_article()
#     def get_article(self):
#         # self.model: 获取所在对象的模型类
#         articles = self.model.filter(status=Article.STATUS_NORMAL)
#         return articles


class Category(models.Model):
    STATUS_NORMAL = 1
    STATUS_DELETE = 0
    STATUS_ITEMS = (
        (STATUS_NORMAL, '正常'),
        (STATUS_DELETE, '删除'),
    )

    name = models.CharField(max_length=50, verbose_name='名称')
    status = models.PositiveIntegerField(default=STATUS_NORMAL,
                                         choices=STATUS_ITEMS,
                                         verbose_name='状态')
    is_nav = models.BooleanField(default=False, verbose_name='是否为导航')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        verbose_name = verbose_name_plural = '分类'

    @classmethod
    def get_navs(cls):
        categories = cls.objects.filter(status=cls.STATUS_NORMAL)
        nav_categories = []
        normal_categories = []
        for cate in categories:
            if cate.is_nav:
                nav_categories.append(cate)
            else:
                normal_categories.append(cate)

        return {
            'navs': nav_categories,
            'categories': normal_categories,
        }

    def __str__(self):
        return self.name


class Tag(models.Model):
    STATUS_NORMAL = 1
    STATUS_DELETE = 0
    STATUS_ITEM = (
        (STATUS_NORMAL, '正常'),
        (STATUS_DELETE, '删除'),
    )

    name = models.CharField(max_length=50, verbose_name='名称')
    status = models.PositiveIntegerField(default=STATUS_NORMAL,
                                         choices=STATUS_ITEM,
                                         verbose_name='状态')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = verbose_name_plural = '标签'

    @classmethod
    def get_all_tags(cls):
        tags = cls.objects.filter(status=cls.STATUS_NORMAL)
        return {
            'tags': tags,
        }


class Article(models.Model):
    STATUS_NORMAL = 0
    STATUS_DELETE = 1
    STATUS_DRAFT = 2
    STATUS_ITEMS = (
        (STATUS_NORMAL, '正常'),
        (STATUS_DELETE, '删除'),
        (STATUS_DRAFT, '草稿'),
    )

    title = models.CharField(max_length=255, verbose_name='标题')
    desc = models.TextField(max_length=1024, blank=True, null=True, verbose_name='摘要')
    content = MDTextField('正文')
    status = models.PositiveIntegerField(default=STATUS_NORMAL,
                                         choices=STATUS_ITEMS,
                                         verbose_name='状态')
    # category = models.ForeignKey(Category, verbose_name='分类', on_delete=models.DO_NOTHING, related_name='category', related_query_name='category')
    category = models.ForeignKey(Category, verbose_name='分类', on_delete=models.DO_NOTHING)
    tag = models.ManyToManyField(Tag, verbose_name='标签')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    pv = models.PositiveIntegerField(default=1)  # 页面浏览量或点击量
    uv = models.PositiveIntegerField(default=1)  # 互联网访问、浏览这个网页的自然人

    content_html = models.TextField(verbose_name='正文 html 代码', blank=True, editable=False)

    is_md = models.BooleanField(default=False, verbose_name="markdown语法")

    class Meta:
        verbose_name = verbose_name_plural = '文章'
        ordering = ['-id']  # 根据 id 进行降序排列

    @classmethod
    def latest_articles(cls):
        queryset = cls.objects.filter(status=cls.STATUS_NORMAL)
        return queryset

    @classmethod
    def hot_posts(cls):
        # 局部数据缓存
        result = cache.get('hot_posts')
        if not result:
            result = cls.objects.filter(status=cls.STATUS_NORMAL).order_by('-pv')
            cache.set('hot_posts', result, 10 * 60)
        return result

    def save(self, *args, **kwargs):
        if self.is_md:
            self.content_html = mistune.markdown(self.content)
        else:
            self.content_html = self.content
        super().save(*args, **kwargs)

    @classmethod
    def get_archive(cls):
        articles = cls.objects.values('id', 'title', 'create_time').order_by('-create_time')
        archive_dict = {}
        for article in articles:
            pub_month = article.get('create_time').strftime('%Y年%m月')
            if pub_month in archive_dict:
                archive_dict[pub_month].append(article)
            else:
                archive_dict[pub_month] = [article]
        data = sorted([{"date": _[0], "articles": _[1]} for _ in archive_dict.items()], key=lambda item: item["date"], reverse=True)
        return data

    def __str__(self):
        return self.title
